#include "qparserwidget.h"

QParserWidget::QParserWidget(QWidget *parent) :
  QWidget(parent)
{
  init();
}

void QParserWidget::addBytes()
{
  variable newvar;
  newvar.fixed=true;
  newvar.length=1;
  newvar.type=BYTEARRAY;
  newvar.matched=false;
  newvar.name=QString("%1").arg(varnumber);
  varnumber++;
  if(varnumber>1024)
    varnumber=1;

  parser->addVariable(newvar,parser->varlistSize());
  testparser();
  emit newVariable(newvar);

  QListWidgetItem *item = new QListWidgetItem;
  item->setIcon(abcIcon);
  varDisplay->insertItem(varDisplay->count(),item);
  varDisplay->setCurrentItem(item);

  int varno = varDisplay->currentRow();
  fixed_length_check->setChecked(true);
  length_spin->setValue(1);
  byte_match_check->setChecked(false);
  byte_array_edit->clear();
  var_name_edit->setText(newvar.name);

  varnameList.insert(varno,newvar.name);
  varTable->setColumnCount(parser->varlistSize());
  varTable->setHorizontalHeaderLabels(varnameList);


}

void QParserWidget::addNumbers()
{
  variable newvar;

  newvar.fixed=true;
  newvar.length=2;
  newvar.type=NUMBER;
  newvar.matched=false;
  newvar.name=QString("%1").arg(varnumber);
  varnumber++;
  if(varnumber>1024)
    varnumber=1;

  parser->addVariable(newvar,parser->varlistSize());
  testparser();
  emit newVariable(newvar);

  QListWidgetItem *item = new QListWidgetItem;
  item->setIcon(numIcon);
  varDisplay->insertItem(varDisplay->count(),item);
  varDisplay->setCurrentItem(item);

  int varno = varDisplay->currentRow();
  fixed_length_check->setChecked(true);
  length_spin->setValue(2);
  byte_match_check->setChecked(false);
  byte_array_edit->clear();
  var_name_edit->setText(newvar.name);

  varnameList.insert(varno,newvar.name);
  varTable->setColumnCount(parser->varlistSize());
  varTable->setHorizontalHeaderLabels(varnameList);
}

void QParserWidget::removeItem()
{
  if(varDisplay->count()>0)
  {
    int delIndex=varDisplay->row(varDisplay->currentItem());
    delete varDisplay->takeItem(delIndex);
    parser->remVariable(delIndex);
    testparser();

 emit removeVariable(delIndex);

    varnameList.removeAt(delIndex);
    varTable->setColumnCount(parser->varlistSize());
    varTable->setHorizontalHeaderLabels(varnameList);

    delIndex=varDisplay->row(varDisplay->currentItem());
    displayConfig(delIndex);
  }
}

void QParserWidget::type_changed(int btnID)
{
  //variable newvar;
  // Change variable type
  if(varDisplay->count()>0)
  {
    int varIndex = varDisplay->currentRow();
    switch(btnID)
    {
    case 0: // BYTE
      varDisplay->currentItem()->setIcon(abcIcon);
      parser->setType(varIndex,BYTEARRAY);
      byte_match_check->setDisabled(false);
      byte_array_edit->setDisabled(false);
      break;
    case 1: // NUMBER
      varDisplay->currentItem()->setIcon(numIcon);
      parser->setType(varIndex,NUMBER);
      byte_match_check->setDisabled(true);
      byte_array_edit->setDisabled(true);
      break;
    default:
      break;
    }
    testparser();
    emit editVariable(varIndex,parser->variableAt(varIndex));
  }
}

void QParserWidget::fixed_checked(bool on)
{

  if(varDisplay->count()>0)
  {
    int varIndex = varDisplay->currentRow();
    parser->setFixed(varIndex,on);

    if(on)
      parser->setLength(varIndex,length_spin->value());

    testparser();
    emit editVariable(varIndex,parser->variableAt(varIndex));
  }
}

void QParserWidget::match_checked(bool on)
{
  if(varDisplay->count()>0)
  {
    int varIndex = varDisplay->currentRow();
    if(on)
    {
      parser->setMatched(varIndex,on);
      QByteArray temparray;
      temparray.append(byte_array_edit->text());
      parser->setArray(varIndex,temparray);
    }
    else
    {
      parser->setMatched(varIndex,false);
    }
    testparser();
    emit editVariable(varIndex,parser->variableAt(varIndex));
  }
}

void QParserWidget::length_changed(int newVal)
{

  if(varDisplay->count()>0)
  {
    int varIndex = varDisplay->currentRow();
    parser->setLength(varIndex,newVal);
    testparser();
    emit editVariable(varIndex,parser->variableAt(varIndex));
  }
}

void QParserWidget::match_changed(QString newString)
{
  if(varDisplay->count()>0)
  {
    int varIndex = varDisplay->currentRow();
    QByteArray temparray;
    temparray.append(byte_array_edit->text());
    parser->setArray(varIndex,temparray);
    testparser();
    emit editVariable(varIndex,parser->variableAt(varIndex));
  }
}

void QParserWidget::name_changed(QString newName)
{
  if(varDisplay->count()>0)
  {
    int varIndex = varDisplay->currentRow();
    parser->setName(varIndex,newName);
    testparser();
    emit editVariable(varIndex,parser->variableAt(varIndex));

    varnameList.replace(varIndex,newName);
    varTable->setHorizontalHeaderLabels(varnameList);
  }

}

void QParserWidget::displayConfig(int varIndex)
{
  variable dispvar;
  if(varIndex>=0){
    dispvar=parser->variableAt(varIndex);

    if(dispvar.type==BYTEARRAY)
    {
      abcRadio->setChecked(true);
      byte_match_check->setDisabled(false);
      byte_array_edit->setDisabled(false);
      disconnect(byte_array_edit,SIGNAL(textChanged(QString)),this,SLOT(match_changed(QString)));
      byte_array_edit->clear();
      byte_array_edit->insert(QString(dispvar.arraytomatch));
      connect(byte_array_edit,SIGNAL(textChanged(QString)),this,SLOT(match_changed(QString)));
      byte_match_check->setChecked(dispvar.matched);

    }
    else
    {
      numRadio->setChecked(true);
      byte_match_check->setDisabled(true);
      byte_array_edit->setDisabled(true);
    }
    disconnect(fixed_length_check,SIGNAL(toggled(bool)),this,SLOT(fixed_checked(bool)));
    fixed_length_check->setChecked(dispvar.fixed);
    connect(fixed_length_check,SIGNAL(toggled(bool)),this,SLOT(fixed_checked(bool)));
    length_spin->setValue(dispvar.length);
    disconnect(var_name_edit,SIGNAL(textChanged(QString)),this,SLOT(name_changed(QString)));
    var_name_edit->clear();
    var_name_edit->insert(dispvar.name);
    connect(var_name_edit,SIGNAL(textChanged(QString)),this,SLOT(name_changed(QString)));
  }
}

void QParserWidget::testparser()
{
  if(!parser->testList())
  {
    parserStatus->showMessage(parser->testout);
    listwidgetpal.setColor(QPalette::Base,"Red");
    varDisplay->setPalette(listwidgetpal);
  }
  else
  {
    parserStatus->showMessage("Variable list is valid");
    listwidgetpal.setColor(QPalette::Base,"White");
    varDisplay->setPalette(listwidgetpal);

    // List for plot settings:
    QList<variable> outlist;

    for(int i=0;i<parser->varlistSize();i++)
    {
      if(parser->variableAt(i).type==BYTEARRAY)
      {
      }
      else
      {
        //logView->appendPlainText(QString("Number: %1").arg(varList.at(i).floatvalue));
        // ONLY OUTPUT NUMBERS FOR NOW
        outlist.append(parser->variableAt(i));
      }
    }
    //emit listChanged(outlist);
  }
}

void QParserWidget::datafromServer(QByteArray datain)
{
  parser->dataparse(datain);
}

void QParserWidget::parser_response(QList<variable> varList,bool valid,QString message)
{
  // Show the user the response from the parsing routine
  QString tempresponse;
  tempresponse.append("Parser response: ");
  tempresponse.append(message);
  if(!valid)
  {

  }
  else
  {
    varTable->insertRow(varTable->rowCount());
    int currentRow;

    currentRow=varTable->rowCount()-1;
    QList<variable> outlist;
    for(int i=0;i<varList.size();i++)
    {
      if(varList.at(i).type==BYTEARRAY)
      {
        QTableWidgetItem *newItem = new QTableWidgetItem(QString(varList.at(i).arrayfound));
        newItem->setFont(tableFont);
        varTable->setItem(currentRow,i, newItem);
        outlist.append(varList.at(i));
      }
      else
      {
        QTableWidgetItem *newItem = new QTableWidgetItem(QString("%1").arg(varList.at(i).floatvalue));
        varTable->setItem(currentRow,i, newItem);
        newItem->setFont(tableFont);
        //logView->appendPlainText(QString("Number: %1").arg(varList.at(i).floatvalue));
        // ONLY OUTPUT NUMBERS FOR NOW
        outlist.append(varList.at(i));
      }
    }

    if(varTable->rowCount()>10)
    {
      varTable->removeRow(0);
    }
    emit newSample(outlist);
  }
  //logView->clear();
  logView->appendPlainText(tempresponse);

}

void QParserWidget::init()
{
  // GUI OBJECTS
  // Variable configuration
  vartypeGroup = new QButtonGroup;
  var_name_label = new QLabel("Name");
  var_name_edit = new QLineEdit;
  propertiesBox = new QGroupBox("Properties");
  propertiesBox->setAlignment(Qt::AlignHCenter);
  propertiesBox->setMaximumWidth(250);
  abcRadio = new QRadioButton("Bytes");
  numRadio = new QRadioButton("Number");
  variabletype = new QComboBox;
  fixed_length_check = new QCheckBox("Fixed length");
  length_spin = new QSpinBox;
  length_spin->setMaximum(1024);
  length_spin->setMinimum(1);
  length_spin->setValue(1);
  length_spin->setFixedWidth(60);
  length_spin->setAlignment(Qt::AlignHCenter);

  byte_match_check = new QCheckBox("Matched");
  byte_array_edit = new QLineEdit;
  byte_array_edit->setMinimumWidth(85);
  byte_array_edit->setMaximumWidth(250);
  save_button = new QPushButton("Save");
  logView = new QPlainTextEdit;
  logShow = new QCheckBox("Show Parser Log");
  varDisplay = new QListWidget;
  abcButton = new QPushButton;
  numButton = new QPushButton;
  delButton = new QPushButton;

  varTable = new QTableWidget;

  // Layout
  mainLayout = new QHBoxLayout;
  setupLayout = new QVBoxLayout;
  ctlButtons = new QHBoxLayout;
  ctlButtons->setSizeConstraint(QLayout::SetMinimumSize);
  settingsLayout = new QVBoxLayout;
  fixedlengthLayout = new QHBoxLayout;
  bytematchLayout = new QHBoxLayout;
  variableConfig = new QVBoxLayout;
  vartypeLayout = new QHBoxLayout;
  fixednmatchedLayout = new QGridLayout;
  varnameLayout = new QHBoxLayout;
  feedbackLayout = new QVBoxLayout;

  parserStatus = new QStatusBar;
  parserStatus->showMessage("Add variables");

  // Variable initialization
  parser = new QParser;
  varnumber = 1;
  tableFont.setFamily("Consolas");
  tableFont.setPointSize(10);

  // Buttons and views tweaks
  abcIcon.addFile("./icons/abc.svg");
  abcButton->setIcon(abcIcon);
  abcButton->setIconSize(QSize(40,40));
  abcButton->setFixedWidth(50);
  numIcon.addFile("./icons/num.svg");
  numButton->setIcon(numIcon);
  numButton->setIconSize(QSize(40,40));
  numButton->setFixedWidth(50);
  delIcon.addFile("./icons/del.svg");
  delButton->setIcon(delIcon);
  delButton->setIconSize(QSize(40,40));
  delButton->setFixedWidth(50);


  fixed_length_check->setChecked(true);
  variabletype->addItem("Bytes");
  variabletype->addItem("Number");
  abcRadio->setChecked(true);
  vartypeGroup->addButton(abcRadio);
  vartypeGroup->setId(abcRadio,0);
  vartypeGroup->addButton(numRadio);
  vartypeGroup->setId(numRadio,1);
  vartypeLayout->addSpacing(10);
  vartypeLayout->addWidget(abcRadio);
  vartypeLayout->addWidget(numRadio);
  vartypeLayout->addSpacing(10);

  logView->setBaseSize(200,50);
  logView->setMinimumSize(200,50);
  logView->setMaximumBlockCount(10);
  logShow->setChecked(true);
  varDisplay->setFlow(QListView::LeftToRight);
  varDisplay->setFixedHeight(65);
  varDisplay->setViewMode(QListView::IconMode);
  varDisplay->setMovement(QListView::Static);
  varDisplay->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
  varDisplay->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  varDisplay->setWrapping(false);
  varDisplay->setBaseSize(200,65);
  varDisplay->setSpacing(4);

  // Layout

  varnameLayout->addWidget(var_name_label);
  varnameLayout->addWidget(var_name_edit);

  fixedlengthLayout->addSpacing(30);
  fixedlengthLayout->addWidget(length_spin);
  fixedlengthLayout->addSpacing(30);

  fixednmatchedLayout->addWidget(fixed_length_check,0,0);
  fixednmatchedLayout->addLayout(fixedlengthLayout,0,1);
  fixednmatchedLayout->addWidget(byte_match_check,1,0);
  fixednmatchedLayout->addWidget(byte_array_edit,1,1);
  fixednmatchedLayout->setSpacing(6);

  variableConfig->addLayout(varnameLayout);
  variableConfig->addLayout(vartypeLayout);
  variableConfig->addLayout(fixednmatchedLayout);
  variableConfig->setSpacing(6);

  ctlButtons->addWidget(abcButton);
  ctlButtons->addWidget(numButton);
  ctlButtons->addWidget(delButton);

  propertiesBox->setLayout(variableConfig);

  setupLayout->addLayout(ctlButtons);
  setupLayout->addWidget(propertiesBox);

  //feedbackLayout->addWidget(logView);
  feedbackLayout->addWidget(varDisplay);
  feedbackLayout->addWidget(varTable);

  mainLayout->addLayout(setupLayout);
  mainLayout->addLayout(feedbackLayout);

  this->setLayout(mainLayout);

  // Signals and slots connections
  connect(abcButton,SIGNAL(clicked()),this,SLOT(addBytes()));
  connect(numButton,SIGNAL(clicked()),this,SLOT(addNumbers()));
  connect(delButton,SIGNAL(clicked()),this,SLOT(removeItem()));
  connect(vartypeGroup,SIGNAL(buttonClicked(int)),this,SLOT(type_changed(int)));
  connect(varDisplay,SIGNAL(currentRowChanged(int)),this,SLOT(displayConfig(int)));
  connect(fixed_length_check,SIGNAL(toggled(bool)),this,SLOT(fixed_checked(bool)));
  connect(length_spin,SIGNAL(valueChanged(int)),this,SLOT(length_changed(int)));
  connect(byte_match_check,SIGNAL(toggled(bool)),this,SLOT(match_checked(bool)));
  connect(byte_array_edit,SIGNAL(textChanged(QString)),this,SLOT(match_changed(QString)));
  connect(var_name_edit,SIGNAL(textChanged(QString)),this,SLOT(name_changed(QString)));
  connect(parser,SIGNAL(outputList(QList<variable>,bool,QString)),this,SLOT(parser_response(QList<variable>,bool,QString)));
  //  connect(logShow,SIGNAL(toggled(bool)),this,SLOT(toggle_log(bool)));
}

